package com.micro.ai.gateway.filter;

import com.micro.ai.commons.util.IdGenerator;
import com.micro.ai.gateway.util.IpUtils;

import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * 全局日志过滤器（优化版）
 * 记录请求开始，生成Trace ID
 * 
 * 优化点：
 * 1. 使用IpUtils统一IP获取逻辑
 * 
 * @author micro-ai
 * @since 0.0.1
 * @version 1.2 优化版本
 */
@Slf4j
@Component
public class GlobalLogFilter implements GlobalFilter, Ordered {

    private static final String TRACE_ID = "traceId";
    private static final String REQUEST_ID = "requestId";
    private static final String START_TIME = "startTime";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        
        // 生成Trace ID
        String traceId = IdGenerator.generateSnowflakeIdString();
        String requestId = request.getHeaders().getFirst("X-Request-Id");
        if (requestId == null) {
            requestId = traceId;
        }
        
        // 设置MDC上下文
        MDC.put(TRACE_ID, traceId);
        MDC.put(REQUEST_ID, requestId);
        MDC.put(START_TIME, String.valueOf(System.currentTimeMillis()));
        
        // 记录请求开始日志
        log.info("请求开始 - Method: {}, URI: {}, RemoteAddr: {}, UserAgent: {}", 
            request.getMethod(), 
            request.getURI(), 
            IpUtils.getClientIp(request),
            request.getHeaders().getFirst("User-Agent"));
        
        // 将Trace ID添加到请求头
        ServerHttpRequest mutatedRequest = request.mutate()
                .header("X-Trace-Id", traceId)
                .header("X-Request-Id", requestId)
                .build();
        
        ServerWebExchange mutatedExchange = exchange.mutate()
                .request(mutatedRequest)
                .build();
        
        return chain.filter(mutatedExchange)
                .doFinally(signalType -> {
                    // 记录请求完成日志
                    ServerHttpResponse response = exchange.getResponse();
                    String startTimeStr = MDC.get(START_TIME);
                    if (startTimeStr != null) {
                        long startTime = Long.parseLong(startTimeStr);
                        long duration = System.currentTimeMillis() - startTime;
                        
                        log.info("请求完成 - Method: {}, URI: {}, Status: {}, Duration: {}ms", 
                            request.getMethod(), 
                            request.getURI(), 
                            response.getStatusCode(), 
                            duration);
                    }
                    
                    // 清理MDC
                    MDC.clear();
                });
    }

    @Override
    public int getOrder() {
        return -1000; // 最高优先级
    }
}
